/**
 * 故障模块
*/

#include "fault.h"
#include "evtqueue.h"

Node faultlist;
uint8_t faultsbuf[sizeof(Node)*32];


/**********************************************************/

/**
 * 故障链表初始化
 * faults：链表头结点
 * 将实时故障链表初始化
*/
static void fault_init_withbuf(Node *faults, void *buf, int buflen) 
{
    INIT_LIST_HEAD(&faults->flist);
    nodebuf_init(&faults->faultbuf, buf, buflen, sizeof(struct task_t));

}

/**
 * 实时故障插入
 * faultEvent：需要插入节点的故障信息
 * 将故障事件数据插入实时故障链表
*/
static void fault_write(Node *faults, EVT_T  faultEvent)
{
    Node* newFaultEvent = (Node*) nodebuf_malloc(&faults->faultbuf,0);
    newFaultEvent->data = faultEvent;
    list_add(&newFaultEvent->flist, &faults->flist);
}

/**
 * 实时读取故障
 * num: 请求读取节点上第num个节点的数据
 * 返回 第number个节点的数据
 * 读取实时链表的第number的数据
*/
static void fault_read(Node *faults, UINT16 num, EVT_T *evt) 
{  
    UINT16 count = 0;
    struct list_head *fault_ptr, *safe_ptr;
    list_for_each_safe(fault_ptr, safe_ptr, &faults->flist) 
	{
        Node *newfault = list_entry(fault_ptr,Node,flist);
        count++;
        if(count == num)
		{
            *evt =  newfault->data;
        }
    }
}

/**
 * 删除故障
 * evt: 要删除的故障事件
 * 删除实时链表的evt类型的故障
*/
static void fault_delete(Node *faults, EVT_T evt)
{
    struct list_head *fault_ptr, *safe_ptr;
    list_for_each_safe(fault_ptr, safe_ptr, &faults->flist) 
	{
        Node *newfault  = list_entry(fault_ptr,Node,flist);
        if (newfault->data.stFaultEvt == evt.stFaultEvt) 
		{
            list_del(fault_ptr);
            nodebuf_free(&faults->faultbuf, newfault);
            return;
        }
    }
    return;
}



/**
*	实时故障链表里故障数量
*/
UINT16 get_fault_num(Node *faults)
{	
	UINT16 count = 0;
    struct list_head *fault_ptr, *safe_ptr;
    list_for_each_safe(fault_ptr, safe_ptr, &faults->flist) 
	{
        Node *newfault = list_entry(fault_ptr,Node,flist);
        count++;       
    }
	return count;
}


/***************************************************************/


static UINT8 RtFaultReflash = 0;



/**
*	实时故障有更新
*/
UINT8 IsRtFaultReflash()
{
	return RtFaultReflash;
}



/**
*	实时故障链表故障数量
*/
UINT16 RtFaultNum()
{	
	return get_fault_num(&faultlist);
}




/**
*	实时故障链表初始化
*/

void RtFaultInit()
{
	fault_init_withbuf(&faultlist, faultsbuf, sizeof(faultsbuf));
}


/**
*	实时故障写入
*/
void RtFaultWrite(EVT_T  faultEvent)
{
	if(faultEvent.eEvtKind != EVT_KIND_FAULT)
	{
		return;
	}
					
	fault_write(&faultlist, faultEvent);
}


/**
*	实时故障读取
*/

void RtFaultRead(UINT16 serialNum, EVT_T *evt)
{	
	fault_read(&faultlist,serialNum, evt);
}


/**
*	实时故障删除
*/
void RtFaultDelet(EVT_T faultEvent)
{
	if(faultEvent.eEvtKind != EVT_KIND_FAULT)
	{
		return;
	}
	fault_delete(&faultlist, faultEvent);

	if(RtFaultNum() == 0)
	{
		RtFaultReflash = FALSE;
	}
	
	
}


/**
 * 故障处理函数
 * faultEvent: 故障事件
 * 故障事件处理函数，三个动作，将故障保存历史记录、
 * 将故障更新到实时故障列表，通知屏幕实时故障信息更新
 * 需要对传入参数的类型进行判断，确定是故障事件，且传入参数合法
*/
void faultHandle (EVT_T   faultEvent)
{
	DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\n   FAULT HANDLE HERE   \n");

    // 1. 将故障保存到历史记录
	
    printf("故障已保存到历史记录.\n");

    // 2. 将故障更新到实时故障列表
	RtFaultWrite(faultEvent);
    printf("故障已更新到实时故障列表.\n");

    // 3. 通知屏幕实时故障信息更新
	RtFaultReflash = TRUE;
	
    printf("实时故障信息已更新.\n");
}




 //测试fault模块
void test_dofault()
{

//    EVT_T emp1 = {
//        .eEvtKind = EVT_KIND_FAULT,
//        .stOpEvt = OP_REV3_DOWN,
//        .time = 1100
//    };
//    EVT_T emp2 = {
//        .eEvtKind = EVT_KIND_FAULT,
//        .stFaultEvt  = FAULT_BALLVAL_ABNORM,
//        .time = 1200
//    };
//    EVT_T emp3 = {
//        .eEvtKind = EVT_KIND_FAULT,
//        .stFaultEvt = FAULT_24V_H,
//        .time = 13000
//    };
//    EVT_T emp4 = {
//        .eEvtKind = EVT_KIND_FAULT,
//        .stExthEvt = EXTH_PUMP_OPEN_EVT,
//        .time = 1400
//    };
//	
//   EVT_T emp5;
//    EVT_T emp6 ;
//    EVT_T emp7;
//	
////	
////    fault_init_withbuf(&faultlist, faultsbuf, sizeof(faultsbuf));
//    
//////    fault_write(&faultlist, emp1);
////    fault_write(&faultlist, emp2);
////    fault_write(&faultlist, emp3);
////    fault_write(&faultlist, emp4);
////    
////    fault_delete(&faultlist, emp4);
////    

////    fault_read(&faultlist,1, &emp5);
////    fault_read(&faultlist,2, &emp6);
////    fault_read(&faultlist,3, &emp7);




//	RtFaultWrite(emp1);
//	RtFaultWrite(emp2);
//	RtFaultWrite(emp3);
//	RtFaultWrite(emp4);
//	
//	  DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\nget num--- from list is ---%d----\n",RtFaultNum());
//	RtFaultRead(1, &emp5);
////	RtFaultRead(2, &emp6);
////	RtFaultRead(3, &emp7);
//	
//	RtFaultDelet(emp5);
//	
//     DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\nget num--- from list is ---%d----\n",RtFaultNum());
//    DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\nget time from list is %d\n",emp5.time);
////    DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\nget time from list is %d\n",emp6.time);
////    DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\nget time from list is %d\n",emp7.time);


//	RtFaultRead(1, &emp5);
////	RtFaultRead(2, &emp6);
////	RtFaultRead(3, &emp7);


//	DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\n after get time from list is %d\n",emp5.time);
////    DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\n after get time from list is %d\n",emp6.time);
//    DEBUG_LOG_INFO(DEBUG_LEVEL_2, "\n after get time from list is %d\n",emp7.time);

}











